package com.tianhao.luo.lazysingleton;

/**
 * 懒汉模式，私有化构造函数，提供一个全局访问点
 * 当访问了这个全局访问点时，再决定是否初始化对象
 * @Date 2019/12/10
 * @Author tianhao.luo
 * @Description
 */

public class LazySingleton{
    /**
     * volatile 防止在new 对象的时候，在字节码层进行指令重排序
     */
    private volatile static LazySingleton lazySingleton;
    private LazySingleton(){

    }
    public static LazySingleton getInstance() {
        //判断当前是否存在了懒加载的实例
        if (null == lazySingleton) {
            //对LazySingleton.class这个懒汉实体类加锁，当存在多个线程访问时，保证拿到的是同一个懒加载实例对象
            //除此之外，还需要在加锁之后判断懒汉实体类是否为空。这是因为，当两个线程同时走到了synchronized关键字时
            //，其中一个线程先进行实例化懒加载实例；另一个线程等他把资源释放之后，也进行了实例化懒加载实例。
            //这就导致实例化的对象不是同一个。所以需要在内部进行判空操作
            synchronized (LazySingleton.class) {
                if (null == lazySingleton) {
                    // 字节码层的处理
                    // 即时编译
                    // 1.分配空间
                    // 2.初始化      假如指令被重排序  3.引用赋值 当第一个线程走到这里的时候，第二个线程就会在第一个判断就返回，由于没有初始化，返回的就是空
                    // 3.引用赋值                      2.初始化
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}